Skip to content

Add emit_message_history to record an agent transcript without seeding it - #74811

Open
pankajastro wants to merge 2 commits into
apache:mainfrom
pankajastro:afl-271-push-the-agent-transcript-to-xcom-without-seeding
Open

pankajastro wants to merge 2 commits into
apache:mainfrom
pankajastro:afl-271-push-the-agent-transcript-to-xcom-without-seeding

Conversation

@pankajastro

@pankajastro pankajastro commented Oct 15, 2026 •

Copy link
Copy Markdown
Member

AgentOperator pushes the transcript to XCom only when message_history is not None.
A single-turn agent that only wants its transcript recorded has to pass message_history=[],
which is the parameter for seeding a conversation.

This adds emit_message_history: bool | None = None:

  • None (default): push the transcript when message_history is set, as before.
  • True: also push it for a run without message_history; the run is not seeded.
  • False: keep a seeded run from pushing it.

emit_message_history resolving to True together with enable_hitl_review raises, for the
same reason message_history does: the post-review transcript is not recoverable.


Was generative AI tooling used to co-author this PR?
  • Yes (Claude Code)

Generated-by: Claude Code (Sonnet 5.5) following the guidelines

🤖 Generated with Claude Code

…g it

Single-turn agents that want their transcript on XCom had to pass
message_history=[], a parameter for seeding a conversation, not for
observing a run. A dedicated flag states that intent directly, and
do_xcom_push=False now also suppresses the transcript push, as it does
the other XCom pushes.

Co-Authored-By: Claude <noreply@anthropic.com>

def _emit_message_history(self, context: Context, result: Any) -> None:
"""Push the full post-run transcript to XCom for the next turn to resume."""
if not self.do_xcom_push:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This gate also stops the push for message_history users, not only the new flag. In 1.0.0rc1 _emit_message_history pushed unconditionally, and stability.rst lists message_history as stable, where narrowing what a feature does needs a major release. A session Dag that sets do_xcom_push=False to keep a big answer out of XCom now pulls nothing on the next turn: with default='[]' every run silently starts fresh, and the store pattern in example_agent.py (no default) saves "None", which fails to parse on the turn after.

Could the gate apply only to the new flag, e.g. if self.message_history is None and not self.do_xcom_push: return? A test that message_history=[] still pushes with do_xcom_push=False would pin it; nothing covers that case today.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, and agreed: the gate narrowed a stable feature. I removed it in 39a4c59.
_emit_message_history now pushes unconditionally again, so a seeded run behaves as in
1.0.0rc1, including with do_xcom_push=False.


Drafted-by: Claude Code (Sonnet 5.5); reviewed by @pankajastro before posting

durable: bool = False,
cache_prompt: bool = True,
message_history: list[ModelMessage] | str | bytes | None = None,
emit_message_history: bool = False,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

emit_message_history=False doesn't stop the push when message_history is set, so False here doesn't really mean "don't emit". Would bool | None = None, resolving to message_history is not None, read better? True opts a single-turn run in, False lets a seeded run opt out, and the transcript gets its own switch instead of riding on do_xcom_push.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, done in 39a4c59: emit_message_history is now bool | None = None, resolved in
__init__ to message_history is not None when unset. True opts a single-turn run in,
False opts a seeded run out, and the transcript no longer depends on do_xcom_push.
test_transcript_emitted_to_xcom covers the seeded, opt-in and opt-out cases, and only
message_history seeds the run.


Drafted-by: Claude Code (Sonnet 5.5); reviewed by @pankajastro before posting

.. note::

``message_history`` cannot be combined with ``enable_hitl_review`` -- the
``message_history`` and ``emit_message_history`` cannot be combined with

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stability.rst and troubleshooting.rst need a line each for this. The stable row names only message_history, so is emit_message_history stable or experimental? And the troubleshooting entry for message_history and enable_hitl_review=True cannot be used together doesn't cover the new emit_message_history error.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added both, in 39a4c59. stability.rst has a row for emit_message_history, marked stable
like message_history (it is additive and the default keeps today's behaviour). The
troubleshooting.rst entry now lists the emit_message_history and enable_hitl_review=True
error alongside the message_history one.


Drafted-by: Claude Code (Sonnet 5.5); reviewed by @pankajastro before posting

Gating the transcript push on do_xcom_push also stopped it for
message_history users, narrowing a stable feature. A tri-state
emit_message_history defaults to whether the run is seeded, so existing
sessions keep pushing, a single-turn run can opt in, and a seeded run
can opt out.

Co-Authored-By: Claude <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants